# -*- coding: utf-8 -*-

'''
Created on 26/11/2011

@author: Luis M. Ugalde
www.forondarena.net

Copyright © 2011 Luis M. Ugalde
Licensed under the terms of the MIT License
(see LICENSE file for details)

This software can't be considered to be even in Alpha state. It still needs a lot of work.
'''


from . import abstractreader
import zmq
import time
from readers.readerexception import ReaderException


class ReaderTail(abstractreader.AbstractReader):
    '''
    Class to "tail -f" a file 
    '''

    def __init__(self):
        print self.__class__.__name__ + ": ReaderTail instance created"
        abstractreader.AbstractReader.__init__(self)

        
    def setSource(self, srcfilename = ""):
        '''
        The source for a file reader is  a regular log file.
        A ReaderTail assumes that the file does not stop getting data.
        It must be capable of detecting file rotation.
        '''

        self.filename = srcfilename


    def connectSources(self):
        '''
        Open the file set with setSource
        '''

        print "{}: Opening file for reading: {}".format(self.__class__.__name__, self.filename)
        try:
            self.file = open(self.filename, 'r')
        except IOError:
            tmpstr= 'Cant open ' + self.filename + ' make sure it is defined in the config file '
            raise ReaderException(tmpstr)


    def closeSources(self):
        '''
        Close the file set with setSource
        '''

        print "{}: Closing the source: {}".format(self.__class__.__name__, self.filename)
        self.file.close()


    def getLines(self):
        '''
        Read lines from a file.
        When file is exhausted, sleep between 0.1 and 1 second waiting for new data.
        This reader simulates a tail -f, therefore it should not end.
        Nevertheless, if a special 'END' line is injected into the source file, it will end.
        This method must detect when a file is rotated. It is not done yet.
        
        The reader won't send data until parsers are available. This is part of the push/pull socket definition.
        This definition also states that reaching the high water mark blocks the socket, so it should behave as desired.
        '''

        step = 0.1
        
        try:
            while True:
                line = self.file.readline()
                
                if not line:
                    if __debug__:
                        print "{}: No data read. Sleeping for {} seconds".format(self.__class__.__name__, 1 if step > 1 else step)
                    time.sleep(1 if step > 1 else step)
                    self.readerbindsocket.send('NODATA')
                    print "{}: Sent NODATA.".format(self.__class__.__name__)
                    step += 0.1
                    continue
            
                step = 0.1
                tmpline = line.rstrip()
                
                if tmpline == 'END':
                    self.readerbindnotifysocket.send('END')
                    print "{}: Sent END.".format(self.__class__.__name__)
                    break
                
                if tmpline == 'TEST':
                    self.readerbindnotifysocket.send('TEST')
                    print "{}: Sent TEST.".format(self.__class__.__name__)
                    continue
                
                self.readerbindsocket.send(tmpline)
                print "{}: Sent {}.".format(self.__class__.__name__, tmpline)

        except IOError:
            tmperror = "Unable to read from " + self.filename
            raise ReaderException(tmperror)
        finally:
            self.closeSources()
            self.closeBindReader()
            self.closeBindNotifyReader()
            self.closeContext()


if __name__ == '__main__':
    print "Please, do not run this"
